import dayjs from "dayjs"
import { requestSDspotMarketZcq } from "@src/api/fetch"
import { yunNao } from "@src/api/yunNao"
import { AsyncRecursion, creatAsyncRecursion } from '@src/utils/asyncRecursion'
import { promisetTimeOut } from "@src/utils/common"
import { throttle } from 'lodash'
import { getPrivateCommonParams } from "@src/spotMarketPrivateData/data"


/** 记录供需timer */
const allSPTimeOutTimerList:Array<ReturnType<typeof setTimeout>> = []
/** 清除所有供需 timeOut */
const clearAllSPTimeOut = () => {
  allSPTimeOutTimerList.forEach(val => clearTimeout(val))
  allSPTimeOutTimerList.length = 0
}


// 用于指定爬取某一天的数据
// const testDay = '2024-11-26'
/**用于过滤获取D1曲线 */
const D1curve = 'D1曲线'

/**----------------------------------------开盘前信息查询   获取时间为每天的每一小时 每小时的 45分钟这个时刻 获取一次  start--------------------------------------------- */
// 获取 开盘信息查询 列表数据
const getOpeningInformationList = async ({headers, certainDate}:{headers:HeadersInit, certainDate?:string}) => {
  try {
    const todayDate =  certainDate || dayjs().format('YYYY-MM-DD')
    const data = await requestSDspotMarketZcq(
      `https://pmos.sd.sgcc.com.cn:18080/zcq/scdxhy/jykpxxcx?method=getSpList&jypz=DXHYZ&sdate=${todayDate}&edate=${todayDate}`,
      undefined,
      { method:'POST', headers }
    )
    // 需要拿到当天的申报列表做过滤，拿D1曲线的数据 根据字符串做过滤
    const resultData = data.data.find((item:any)=>{
     return item.kpmc.includes(D1curve)
    })
    return Promise.resolve(resultData)
  } catch(e) {
    console.error(e)
  }
}


// 根据上面的开盘信息查询 列表数据 获取 开盘信息中对应的具体月内集中交易数据列表  
export const getOpeningInformationDetailList = async ({headers, unitid, certainDate = '', nowStr = '', isHandler = false}:{headers:HeadersInit, unitid:string, nowStr?:string,certainDate?:string, isHandler?:boolean}) => {
  console.log(`进入开盘前信息查询 getOpeningInformationDetailList${dayjs().format('YYYY-MM-DD HH:ss:mm')}`)
  // 只爬取周二的当天的 15 刻中的数据
  if(!isHandler && (dayjs().day() !== 2 && !/^.*15$/.test(nowStr))) return

  try {
    const todayDate =  certainDate || dayjs().format('YYYY-MM-DD')
    const { kpid } = await getOpeningInformationList({headers, certainDate})
    /**没有获取到 kpid 证明当天没有D1曲线的开盘信息就不往下执行 */
    if(!kpid) return
    const data = await requestSDspotMarketZcq(
      `https://pmos.sd.sgcc.com.cn:18080/zcq/scdxhy/jykpxxcx?method=getJyInfo&kpid=${kpid}`,
      undefined,
      { method:'POST', headers }
    )
    console.log(
      `%c 爬取开盘前信息 getOpeningInformationDetailList，每一个钟 15 分执行一次`,
      'background:#35495e ; padding: 1px; border-radius: 3px 0 0 3px;  color: #fff',
    )
    console.log('开盘前信息查询data', data)
    const saveDataList = {
      ...getPrivateCommonParams({thirdId:unitid}),
      itemCode: 'monthly_centralized_trading_detail',
      targetDate:todayDate,
      data:data?.data || []
    }
    
    console.log(`存储数据：爬取开盘前信息${dayjs().format('YYYY-MM-DD HH:ss:mm')}`, saveDataList)
    await yunNao.saveJson(saveDataList)
    return Promise.resolve(data)
  } catch(e) {
    console.error(e)
  }
}

/**----------------------------------------开盘前信息查询 end--------------------------------------------- */


/**----------------------------------------申报中 集中竞价信息查询 周二早上 9-10 1min start--------------------------------------------- */
// 获取 集中竞价交易申报列表
const getCentralizedBiddingList = async ({headers}:{headers:HeadersInit}) => {
  const today = dayjs().format('YYYY-MM-DD')
  try {
    const data = await requestSDspotMarketZcq(
      `https://pmos.sd.sgcc.com.cn:18080/zcq/dxhyjy/jzjzjy.do?method=getKpxx&jylx=0&jyxz=all&sdate=${today}&edate=${today}&_=${dayjs().valueOf()}`,
      undefined,
      { method:'GET', headers }
    )
    // 需要拿到当天的申报列表做过滤，拿D1曲线的数据 根据字符串做过滤
    const resultData = data.data.find((item:any)=>{
      return item.KPMC.includes(D1curve)
    })
    return Promise.resolve(resultData)
  } catch(e) {
    console.error(e)
  }
}


interface BiddingListObjType {
  data:Array<any>,
  KPID:string
}
// 供需数据列表
let biddingListObj = {} as BiddingListObjType

// 获取一个供需数据的方法 根据  getCentralizedBiddingListTwo 获取的列表数据 ，遍历列表查询每一条详情里面的数据并保存
const getCentralizedBiddingDetailOne = async ({headers, KPID, JYDM}:{headers:HeadersInit, KPID:string, JYDM:string}) => {
  try {
    const data = await requestSDspotMarketZcq(
      `https://pmos.sd.sgcc.com.cn:18080/zcq/dxhyjy/jzjzjy.do?method=getJzjzjySbXxSum&kpid=${KPID}&jydm=${JYDM}&num=0&jyjd=2&cxsj=&_=${dayjs().valueOf()}`,
      undefined,
      { method:'GET', headers }
    )
    console.log(
      `%c 爬取申报中的数据详情`,
      'background:#35495e ; padding: 1px; border-radius: 3px 0 0 3px;  color: #fff',
    )
        // TODO: 供需mock数据
  //   let data = {
  //     getGpxx: {
  //         data: [
  //             {
  //                 dj: index,
  //                 name: "供应五",
  //                 dl: "6300"
  //             },
  //             {
  //                 dj: "319.8",
  //                 name: "供应四",
  //                 dl: "1200"
  //             },
  //             {
  //                 dj: "310",
  //                 name: "供应三",
  //                 dl: "360"
  //             },
  //             {
  //                 dj: "300",
  //                 name: "供应二",
  //                 dl: "800"
  //             },
  //             {
  //                 dj: "245.4",
  //                 name: "供应一",
  //                 dl: "11810"
  //             },
  //             {
  //                 dj: "403.3",
  //                 name: "需求一",
  //                 dl: "1490"
  //             },
  //             {
  //                 dj: "374.8",
  //                 name: "需求二",
  //                 dl: "20"
  //             },
  //             {
  //                 dj: "345",
  //                 name: "需求三",
  //                 dl: "100"
  //             },
  //             {
  //                 dj: "320",
  //                 name: "需求四",
  //                 dl: "100"
  //             },
  //             {
  //                 dj: "120",
  //                 name: "需求五",
  //                 dl: "120"
  //             }
  //         ]
  //     },
  //     "getJyMx": {
  //         "contiStart": "00:00",
  //         "data": [],
  //         "contiEnd": "00:00",
  //         "aggrEnd": "00:00",
  //         "yestclose": "",
  //         "aggrStart": "00:00",
  //         "range": ""
  //     },
  //     "getCjjl": {
  //         "data": []
  //     },
  //     "getCjjlForTime": {
  //         "data": []
  //     },
  //     "getCjjlForJg": {
  //         "data": []
  //     },
  //     "getJyMxDay": {
  //         "data": []
  //     },
  //     "getSjCenter": {
  //         "data": []
  //     }
  // }
    const newDataObj = {} as any
    newDataObj.tradeCode = JYDM
    newDataObj.data = data?.getGpxx?.data || []
    console.log('getCentralizedBiddingDetailOne 每一条详情数据', newDataObj);
    return Promise.resolve(newDataObj)
  } catch(e) {
    console.error(e)
  }
}

/** 判断当前时间能否获取供需数据 周二 9:00-10:00才可以获取*/
const isGetSupplyDemandData = () => {
  const nowNum = Number(dayjs().format('HHmm'))
  // 这里提前和延后两分钟
  const getDataStartEnd = [900, 1000]
  return dayjs().day() === 2 && nowNum > getDataStartEnd[0] && nowNum < getDataStartEnd[1]
}

// 根据 集中竞价交易申报列表 中的 D1 曲线的数据里面的 kpId 获取对应天数列表
const getCentralizedBiddingDataLoop = async ({headers, unitid}:{headers:HeadersInit, unitid:string}) => {
  try {
    clearAllSPTimeOut()
    console.log('进入供需数据详情爬取入口')
    if(!isGetSupplyDemandData()) {
      /** 非交易时间段清空存的数据 */
      biddingListObj = {} as any
      return 
    }

    if(!Object.keys(biddingListObj).length) {
      const { KPID } = await getCentralizedBiddingList({headers})
      const { data } = await requestSDspotMarketZcq(
        `https://pmos.sd.sgcc.com.cn:18080/zcq/dxhyjy/jzjzjy.do?method=getFpgJyjgInfo&kpId=${KPID}&jyjd=`,
        undefined,
        { method:'POST', headers }
      ) 
      biddingListObj = {
        data: data || [],
        KPID:KPID
      }
    }

    const paramsList = biddingListObj?.data?.map((item:any)=> ({headers, KPID:biddingListObj?.KPID, JYDM:item?.JYDM}))

    const allNodeData = await creatAsyncRecursion(AsyncRecursion, {
      stepAsyncFnParamsList: paramsList,
      stepAsyncFn: getCentralizedBiddingDetailOne,
      stepCb: async () => await promisetTimeOut(1000), // 每种类型隔, 防反爬和日期错误
      stepAsyncNum: 1,
      errBreak: false
    }).start()

    const saveDataList = {
      ...getPrivateCommonParams({thirdId:unitid}),
      itemCode: 'concentrated_bidding_detail',
      declarationStartDate:dayjs().format('YYYY-MM-DD'),
      dataList:(allNodeData?.allResultList || []).flat(),
    }

    console.log(
      `%c 保存供需详情数据`,
      'background:#35495e ; padding: 1px; border-radius: 3px 0 0 3px;  color: #fff',
    )

    console.log(`存储数据：详情 ${dayjs().format('YYYY-MM-DD HH:ss:mm')}`, saveDataList)
    await yunNao.saveJson(saveDataList)
    console.log("爬取详情数据存储成功", dayjs().format("YYYY-MM-DD HH:mm:ss"))
    return Promise.resolve(saveDataList)
  } catch(e){
    console.log('e: ', e);
  } finally {
    clearAllSPTimeOut()
    const SPtimer = setTimeout(() => getCentralizedBiddingDataLoop({headers, unitid}), 1000 * 60) // 一分钟执行一次
    allSPTimeOutTimerList.push(SPtimer)
  }
}


export const getCentralizedBiddingDataLoopThrottle = throttle(getCentralizedBiddingDataLoop, 2000, {trailing:true, leading: false})

/**----------------------------------------申报中 集中竞价信息查询 end--------------------------------------------- */



/**----------------------------------------开盘后 信息查询  每天 每个钟 的 :15 时刻这个点获取一次数据 start--------------------------------------------- */

// 开盘后信息列表
const afterOpeningBell = async ({headers}:{headers:HeadersInit}) => {
  const todayDate =  dayjs().format('YYYY-MM-DD')
  try {
    const data = await requestSDspotMarketZcq(
      `https://pmos.sd.sgcc.com.cn:18080/zcq/dxhyjy/jzjzjy.do?method=getKpxx&jylx=0&jyxz=all&sdate=${todayDate}&edate=${todayDate}&_=${dayjs().valueOf()}`,
      undefined,
      { method:'GET', headers }
    )
    // 需要拿到当天的申报列表做过滤，拿D1曲线的数据 根据字符串做过滤
    const resultData = data.data.find((item:any)=>{
      return item.KPMC.includes(D1curve)
    })
    return Promise.resolve(resultData)
  } catch(e) {
    console.error(e)
  }
}


// 开盘后集中竞价列表信息  开盘后信息可以爬取到但是暂时不用这里的数据
export const getAfterOpeningBellList = async ({headers, unitid, nowStr}:{headers:HeadersInit, unitid:string, nowStr:string}) => {
  console.log(`进入开盘后信息查询 getAfterOpeningBellList${dayjs().format('YYYY-MM-DD HH:ss:mm')}`)
  if(!/^.*15$/.test(nowStr)) return
  try {
    const { KPID } = await afterOpeningBell({headers})
    const { data } = await requestSDspotMarketZcq(
      `https://pmos.sd.sgcc.com.cn:18080/zcq/dxhyjy/jzjzjy.do?method=getFpgJyjgInfo&kpId=${KPID}&jyjd=`,
      undefined,
      { method:'POST', headers }
    )
    console.log(
      `%c 获取开盘后列表信息，每一个钟 :15 执行一次`,
      'background:#35495e ; padding: 1px; border-radius: 3px 0 0 3px;  color: #fff',
    )

    const saveDataList = {
      ...getPrivateCommonParams({thirdId:unitid}),
      itemCode: 'concentrated_bidding',
      data:data
    }
    console.log(`存储数据：开盘后${dayjs().format('YYYY-MM-DD HH:ss:mm')}`, saveDataList)
    // 保存数据到云脑
    await yunNao.saveJson(saveDataList)
    return Promise.resolve(data)
  } catch(e) {
    console.error(e)
  }
}


/**----------------------------------------开盘后 信息查询 end--------------------------------------------- */
